using System;
using System.Collections.Generic;

public interface IState<T>
{
    void OnEnter(T owner);
    void OnUpdate(T owner);
    void OnFixedUpdate(T owner);
    void OnExit(T owner);
}

public class StateMachine<T>
{
    private T owner;
    private IState<T> currentState;
    private Dictionary<Type, IState<T>> stateMap = new Dictionary<Type, IState<T>>();

    public StateMachine(T owner)
    {
        this.owner = owner;
    }

    public void AddState(IState<T> state)
    {
        stateMap[state.GetType()] = state;
    }

    public void ChangeState<U>() where U : IState<T>
    {
        if (currentState != null)
            currentState.OnExit(owner);

        if (stateMap.TryGetValue(typeof(U), out IState<T> newState))
        {
            currentState = newState;
            currentState.OnEnter(owner);
        }
    }

    public void Update()
    {
        currentState?.OnUpdate(owner);
    }
    
    public void FixedUpdate()
    {
        currentState?.OnFixedUpdate(owner);
    }
}
